package com.dji.sample.common.util;

import com.dji.sample.component.oss.model.OssConfiguration;
import com.dji.sample.component.oss.service.impl.OssServiceContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

/**
 * 缩略图生成工具类
 * 提供从MinIO获取原图并生成缩略图的功能
 * 
 * @author system
 * @version 1.0
 * @date 2024/12/27
 */
@Component
@Slf4j
public class ThumbnailUtil {

    @Autowired
    private OssServiceContext ossServiceContext;

    /**
     * 默认缩略图宽度
     */
    private static final int DEFAULT_THUMBNAIL_WIDTH = 200;

    /**
     * 默认缩略图高度
     */
    private static final int DEFAULT_THUMBNAIL_HEIGHT = 200;

    /**
     * 缩略图文件夹前缀
     */
    private static final String THUMBNAIL_PREFIX = "thumbnails/";

    /**
     * 根据原图objectKey生成缩略图并返回缩略图的objectKey
     * 
     * @param originalObjectKey 原图的objectKey
     * @return 缩略图的objectKey
     * @throws RuntimeException 当处理失败时抛出异常
     */
    public String generateThumbnailUrl(String originalObjectKey) {
        return generateThumbnailUrl(originalObjectKey, DEFAULT_THUMBNAIL_WIDTH, DEFAULT_THUMBNAIL_HEIGHT);
    }

    /**
     * 根据原图objectKey生成指定尺寸的缩略图并返回缩略图的objectKey
     * 
     * @param originalObjectKey 原图的objectKey
     * @param width 缩略图宽度
     * @param height 缩略图高度
     * @return 缩略图的objectKey
     * @throws RuntimeException 当处理失败时抛出异常
     */
    public String generateThumbnailUrl(String originalObjectKey, int width, int height) {
        try {
            log.info("开始生成缩略图，原图objectKey: {}, 目标尺寸: {}x{}", originalObjectKey, width, height);

            // 1. 从MinIO获取原图
            InputStream originalImageStream = getOriginalImageFromMinio(originalObjectKey);
            
            // 2. 生成缩略图
            byte[] thumbnailBytes = generateThumbnail(originalImageStream, width, height);
            
            // 3. 生成缩略图的objectKey
            String thumbnailObjectKey = generateThumbnailObjectKey(originalObjectKey);
            
            // 4. 上传缩略图到MinIO
            uploadThumbnailToMinio(thumbnailObjectKey, thumbnailBytes);
            
            log.info("缩略图生成成功，原图: {}, 缩略图objectKey: {}", originalObjectKey, thumbnailObjectKey);
            return thumbnailObjectKey;
            
        } catch (Exception e) {
            log.error("生成缩略图失败，原图objectKey: {}, 错误信息: {}", originalObjectKey, e.getMessage(), e);
            throw new RuntimeException("生成缩略图失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从MinIO获取原图
     * 
     * @param objectKey 原图的objectKey
     * @return 原图的输入流
     * @throws RuntimeException 当获取失败时抛出异常
     */
    private InputStream getOriginalImageFromMinio(String objectKey) {
        try {
            log.debug("从MinIO获取原图，objectKey: {}", objectKey);
            InputStream inputStream = ossServiceContext.getObject(OssConfiguration.bucket, objectKey);
            if (inputStream == null) {
                throw new RuntimeException("无法从MinIO获取原图，objectKey: " + objectKey);
            }
            return inputStream;
        } catch (Exception e) {
            log.error("从MinIO获取原图失败，objectKey: {}, 错误信息: {}", objectKey, e.getMessage(), e);
            throw new RuntimeException("从MinIO获取原图失败: " + e.getMessage(), e);
        }
    }

    /**
     * 生成缩略图
     * 
     * @param originalImageStream 原图输入流
     * @param width 目标宽度
     * @param height 目标高度
     * @return 缩略图字节数组
     * @throws IOException 当图片处理失败时抛出异常
     */
    private byte[] generateThumbnail(InputStream originalImageStream, int width, int height) throws IOException {
        log.debug("开始生成缩略图，目标尺寸: {}x{}", width, height);
        
        // 读取原图
        BufferedImage originalImage = ImageIO.read(originalImageStream);
        if (originalImage == null) {
            throw new IOException("无法读取原图，可能不是有效的图片格式");
        }
        
        // 计算缩略图尺寸，保持宽高比
        Dimension thumbnailSize = calculateThumbnailSize(originalImage.getWidth(), originalImage.getHeight(), width, height);
        
        // 创建缩略图
        BufferedImage thumbnailImage = new BufferedImage(
            thumbnailSize.width, 
            thumbnailSize.height, 
            BufferedImage.TYPE_INT_RGB
        );
        
        // 绘制缩略图
        Graphics2D graphics = thumbnailImage.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        graphics.drawImage(originalImage, 0, 0, thumbnailSize.width, thumbnailSize.height, null);
        graphics.dispose();
        
        // 将缩略图转换为字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(thumbnailImage, "jpg", outputStream);
        
        byte[] thumbnailBytes = outputStream.toByteArray();
        log.debug("缩略图生成完成，尺寸: {}x{}, 文件大小: {} bytes", 
            thumbnailSize.width, thumbnailSize.height, thumbnailBytes.length);
        
        return thumbnailBytes;
    }

    /**
     * 计算缩略图尺寸，保持原图宽高比
     * 
     * @param originalWidth 原图宽度
     * @param originalHeight 原图高度
     * @param targetWidth 目标宽度
     * @param targetHeight 目标高度
     * @return 计算后的缩略图尺寸
     */
    private Dimension calculateThumbnailSize(int originalWidth, int originalHeight, int targetWidth, int targetHeight) {
        double widthRatio = (double) targetWidth / originalWidth;
        double heightRatio = (double) targetHeight / originalHeight;
        double ratio = Math.min(widthRatio, heightRatio);
        
        int thumbnailWidth = (int) (originalWidth * ratio);
        int thumbnailHeight = (int) (originalHeight * ratio);
        
        return new Dimension(thumbnailWidth, thumbnailHeight);
    }

    /**
     * 生成缩略图的objectKey
     * 
     * @param originalObjectKey 原图的objectKey
     * @return 缩略图的objectKey
     */
    private String generateThumbnailObjectKey(String originalObjectKey) {
        // 提取原图文件名（不包含路径）
        String fileName = originalObjectKey;
        if (originalObjectKey.contains("/")) {
            fileName = originalObjectKey.substring(originalObjectKey.lastIndexOf("/") + 1);
        }
        
        // 提取文件名和扩展名
        String nameWithoutExt = fileName;
        String extension = "jpg"; // 缩略图统一使用jpg格式
        
        if (fileName.contains(".")) {
            nameWithoutExt = fileName.substring(0, fileName.lastIndexOf("."));
        }
        
        // 生成唯一的缩略图文件名
        String thumbnailFileName = nameWithoutExt + "_thumbnail_" + UUID.randomUUID().toString().substring(0, 8) + "." + extension;
        
        // 组合完整的objectKey
        String thumbnailObjectKey = THUMBNAIL_PREFIX + thumbnailFileName;
        
        log.debug("生成缩略图objectKey: {} -> {}", originalObjectKey, thumbnailObjectKey);
        return thumbnailObjectKey;
    }

    /**
     * 上传缩略图到MinIO
     * 
     * @param thumbnailObjectKey 缩略图的objectKey
     * @param thumbnailBytes 缩略图字节数组
     * @throws RuntimeException 当上传失败时抛出异常
     */
    private void uploadThumbnailToMinio(String thumbnailObjectKey, byte[] thumbnailBytes) {
        try {
            log.debug("上传缩略图到MinIO，objectKey: {}, 文件大小: {} bytes", thumbnailObjectKey, thumbnailBytes.length);
            
            ByteArrayInputStream inputStream = new ByteArrayInputStream(thumbnailBytes);
            ossServiceContext.putObject(OssConfiguration.bucket, thumbnailObjectKey, inputStream);
            
            log.debug("缩略图上传成功，objectKey: {}", thumbnailObjectKey);
        } catch (Exception e) {
            log.error("上传缩略图到MinIO失败，objectKey: {}, 错误信息: {}", thumbnailObjectKey, e.getMessage(), e);
            throw new RuntimeException("上传缩略图到MinIO失败: " + e.getMessage(), e);
        }
    }

//    /**
//     * 获取缩略图的永久URL
//     *
//     * @param thumbnailObjectKey 缩略图的objectKey
//     * @return 缩略图的永久URL
//     * @throws RuntimeException 当获取URL失败时抛出异常
//     */
//    private String getThumbnailPermanentUrl(String thumbnailObjectKey) {
//        try {
//            log.debug("获取缩略图永久URL，objectKey: {}", thumbnailObjectKey);
//
//            URL url = ossServiceContext.getObjectUrl(OssConfiguration.bucket, thumbnailObjectKey);
//            if (url == null) {
//                throw new RuntimeException("无法获取缩略图URL，objectKey: " + thumbnailObjectKey);
//            }
//
//            String urlString = url.toString();
//            log.debug("获取缩略图URL成功，objectKey: {}, URL: {}", thumbnailObjectKey, urlString);
//
//            return urlString;
//        } catch (Exception e) {
//            log.error("获取缩略图URL失败，objectKey: {}, 错误信息: {}", thumbnailObjectKey, e.getMessage(), e);
//            throw new RuntimeException("获取缩略图URL失败: " + e.getMessage(), e);
//        }
//    }
}